use std::{cell::Cell, error::Error, path::PathBuf, sync::Arc};

use egui::{Color32, Id, Stroke, Vec2};
use QcCore::ecs::components::material_render::MaterialRender;
use QcTools::sync::Lazy;
use QcUI::core::context::UiContext;

use crate::core::{context::Context, message::EditorMessage};

use crate::inspector::{ComponentState, InspectorContext, InspectorTrait};

#[derive(Debug)]
pub struct MaterialRenderState {
    show_texture_window: bool,
    materials: Vec<String>,
    context: Arc<Context>,
}

static MATERIAL_FILE_EXT: Lazy<Vec<&str>> = Lazy::new(|| vec!["mtl"]);

impl MaterialRenderState {
    pub fn new(context: Arc<Context>) -> MaterialRenderState {
        let resource_manager = context.clone().resource_manager.clone();

        let path = resource_manager
            .get_assets_path()
            .expect("获取 assets 路径失败");

        let materials = Self::find_material(&path, &path).unwrap();
        println!("{:?}", materials);

        Self {
            show_texture_window: false,
            materials,
            context,
        }
    }

    pub fn find_material(path: &PathBuf, prefix: &PathBuf) -> Result<Vec<String>, Box<dyn Error>> {
        let mut result = vec![];
        if path.exists() {
            if path.is_dir() {
                for entry in path.read_dir()? {
                    let path = entry?.path();
                    result.append(&mut Self::find_material(&path, prefix)?);
                }
            } else {
                if let Some(ext_name) = path.extension() {
                    let ext_name = ext_name.to_os_string().into_string().unwrap();

                    if MATERIAL_FILE_EXT.contains(&&*ext_name) {
                        let path = path.strip_prefix(prefix)?;
                        result.push(path.to_str().unwrap().to_string());
                    }
                }
            }
        }

        Ok(result)
    }
}

impl InspectorTrait for MaterialRender {
    fn inspector(&mut self, ctx: &mut InspectorContext, state: &mut ComponentState) {
        let ComponentState::MaterialRender(state) = state else {
            panic!("属性面板组件状态传递错误")
        };

        egui::CollapsingHeader::new("MaterialRender")
            .default_open(true)
            .show(ctx.ui, |ui| {
                ui.group(|ui| {
                    ui.set_min_width(ui.available_width() - 5.);
                    egui::Grid::new("MaterialRender")
                        .num_columns(2)
                        .min_col_width(70.)
                        .spacing(Vec2::new(10., 10.))
                        .show(ui, |ui| {
                            ui.label("Material");
                            ui.horizontal(|ui| {
                                let mut str = self.material_list.first().unwrap().name.clone();
                                let width = ui.available_width() - 50.;
                                ui.scope(|ui| {
                                    ui.style_mut().visuals.text_cursor.width = 0.;
                                    let mut size = ui.spacing().interact_size;
                                    size.x = ui.available_width() - 20.;
                                    ui.horizontal(|ui| {
                                        ui.add_sized(size, egui::TextEdit::singleline(&mut str));
                                        ui.add_space(5.);

                                        let res = ui.small_button("🐮");
                                        if res.clicked() {
                                            state.show_texture_window = true;
                                        }

                                        if state.show_texture_window {
                                            let rect = ui.min_rect().translate(Vec2::new(0., 25.));

                                            egui::Area::new(Id::new("MaterialFind"))
                                                .fixed_pos(rect.min)
                                                .show(ui.ctx(), |ui| {
                                                    for text in &state.materials {
                                                        let button = egui::Button::new(text)
                                                            .stroke(Stroke::NONE)
                                                            .min_size(Vec2::new(rect.width(), 0.));
                                                        if ui.add(button).clicked() {
                                                            state.show_texture_window = false;
                                                            ctx.sender
                                                                .send(EditorMessage::SetMaterial(
                                                                    text.to_string(),
                                                                ))
                                                                .unwrap();
                                                        }
                                                    }
                                                });
                                        }
                                        ui.add_space(5.);
                                    });
                                });
                            });
                            ui.end_row();
                        })
                });
            });
    }
}
